<template>
	<view class="root">
		<view class="fd-row jc-sa">
			<label
				v-for="(title, key) in tabs"
				:key="key"
				@click="switchTab(key)"
				:class="[{ active: key === tabKey }, 'top-bar jc-center color-1b1b1b fs-30']"
			>
				{{ title }}
			</label>
		</view>

		<scroll-view
			:scroll-y="true"
			:style="{
				margin: `30rpx`,
				boxShadow: `0 0 16rpx 0 rgba(0, 0, 0, 0.15)`,
			}"
			class="br-10 f1 oh"
		>
			<view :style="{ padding: `30rpx`, borderBottom: `1rpx solid #eee` }" class="ai-center">
				<image
					:style="{ width: `180rpx`, height: `180rpx` }"
					:src="`/static/images/pic-${tabKey || 'transport'}.png`"
					mode="aspectFit"
				/>
				<text class="mt-30 fs-28 color-3f3938">
					{{ tabs[tabKey] }}
				</text>
				<text class="mt-10 fs-24 color-a09d9c"> 专业技术人员直接上门为您服务 </text>
			</view>

			<view
				v-for="(option, optionKey) in viewModel[tabKey]"
				:key="optionKey"
				:style="{
					padding: `18rpx 30rpx`,
					borderBottom: `1rpx solid #eee`,
				}"
				class="fd-row ai-center"
			>
				<block v-if="option.el">
					<image
						class="width-34 height-36 mr-36"
						:src="`/static/images/icon-${option.icon}.png`"
						mode="aspectFit"
					/>
					<label
						v-if="option.el === 'label'"
						:style="{ color: option.value ? '#000' : '#888' }"
						class="f1 fs-28 lh-2"
						@click="operation($event, optionKey)"
					>
						{{ option.value || option.placeholder }}
					</label>

					<input
						v-if="option.el === 'input'"
						:value="option.value"
						:type="option.type"
						:placeholder="option.placeholder"
						:maxlength="option.maxlength || -1"
						:disabled="option.disabled"
						@input="operation($event, optionKey)"
						class="f1 input fs-28 height-54"
						placeholder-class="color-999"
					/>

					<picker
						v-if="option.el === 'picker'"
						:mode="option.mode"
						:range="option.range"
						:range-key="option.rangeKey"
						class="f1 height-54"
						@change="operation($event, optionKey)"
					>
						<text
							:style="{ color: option.value ? '#000' : '#888' }"
							class="f1 fs-28 lh-2"
						>
							{{ option.value || option.placeholder }}
						</text>
					</picker>
					<uni-date-time-picker
						v-if="option.el === 'dateTimePicker'"
						:placeholder="option.placeholder"
						:value="option.value"
						:start="option.start"
						:style="{ display: `flex`, alignItems: `center` }"
						@change="operation($event, optionKey)"
						class="f1 height-54"
					/>

					<view v-if="option.el === 'image'" class="fd-row flex-wrap">
						<image
							:style="{ width: `112rpx`, height: `112rpx` }"
							v-for="(src, index) in option.value"
							:key="index"
							:src="src"
							@click="tapPhotos(optionKey, index)"
							mode="aspectFill"
							class="mr-12 br-8"
						/>
						<image
							v-if="option.value.length < option.maxlength"
							:style="{ width: `112rpx`, height: `112rpx` }"
							:src="`/static/images/pic-upload_${optionKey}.png`"
							mode="aspectFill"
							@click="operation($event, optionKey)"
							class="mr-12 br-8"
						/>
					</view>

					<label class="f1 height-54" v-if="option.el === 'switch'">
						<text class="f1 fs-28 color-888">
							{{ option.placeholder }}
						</text>
						<switch
							color="#fff"
							:type="option.type"
							:checked="option.checked"
							@change="operation($event, optionKey)"
						/>
					</label>
					<uni-icons v-if="option.next" type="arrowright" color="#999" />
				</block>

				<block v-else>
					<view
						v-for="(item, itemKey) in option"
						:key="itemKey"
						class="f1 fd-row ai-center"
					>
						<image
							class="width-34 height-36 mr-36"
							:src="`/static/images/icon-${item.icon}.png`"
							mode="aspectFit"
						/>
						<input
							v-if="item.el === 'input'"
							:value="item.value"
							:type="item.type"
							:placeholder="item.placeholder"
							:maxlength="item.maxlength"
							:disabled="item.disabled"
							@input="operation($event, optionKey, itemKey)"
							class="f1 input fs-28 height-54"
							placeholder-class="color-999"
						/>
					</view>
				</block>
			</view>
		</scroll-view>

		<button
			:plain="true"
			:style="{ margin: `10rpx 30rpx 50rpx` }"
			hover-class="tap-hover"
			class="bgc-3ec483 border-none br-10 color-fff br-10 fs-30 lh-3"
			@click="nextStep"
		>
			{{
				(viewModel.transport.whetherNeedCarry.checked && tabKey === "transport") ||
				(viewModel.carry.whetherNeedInstall.checked && tabKey === "carry")
					? "下一步"
					: "发布"
			}}
		</button>
	</view>
</template>

<script lang="ts">
	import { Vue, Component } from "vue-property-decorator";
	import uniIcons from "@/components/uni-icons.vue";
	import uniDateTimePicker from "@/components/uni-datetime-picker/uni-datetime-picker.vue";
	import { $config } from "@/common";
	import { formatDate, Storage } from "@/libs/utils";

	@Component({ components: { uniIcons, uniDateTimePicker } })
	export default class PlaceOrder extends Vue {
		// component property
		tabs: AnyObject = {
			transport: "城配运输",
			carry: "搬运服务",
			install: "安装服务",
		};
		tabKey: string = "transport";

		submitParams: AnyObject = {};

		goodsTypes: AnyObject[] = [];

		viewModel: AnyObject = {
			transport: {
				goodsType: {
					name: "cid",
					el: "picker",
					mode: "selector",
					range: [],
					rangeKey: "name",
					value: "",
					placeholder: "选择货品类型",
					next: true,
					icon: "choose_orange",
				},
				sendAddress: {
					name: "delivery_address",
					el: "label",
					type: "text",
					value: "",
					placeholder: "选择送货地址",
					next: true,
					icon: "address",
				},
				receiveAddress: {
					name: "receiving_address",
					el: "label",
					type: "text",
					value: "",
					placeholder: "选择收货地址",
					next: true,
					icon: "address",
				},
				distributionDate: {
					name: "delivery_time",
					el: "dateTimePicker",
					value: "",
					start: formatDate(),
					placeholder: "选择配送时间",
					next: true,
					icon: "time",
				},
				sender: {
					name: "sender_name",
					el: "input",
					value: "",
					maxlength: 9,
					type: "text",
					placeholder: "寄件人姓名",
					icon: "user_green",
				},
				senderPhoneNumber: {
					name: "sender_phone",
					el: "input",
					value: "",
					maxlength: 11,
					type: "number",
					placeholder: "寄件人手机号码",
					icon: "phone_green",
				},
				receiver: {
					name: "recipient_name",
					el: "input",
					value: "",
					maxlength: 9,
					type: "text",
					placeholder: "收件人姓名",
					icon: "user_orange",
				},
				receiverPhoneNumber: {
					name: "recipient_phone",
					el: "input",
					value: "",
					maxlength: 11,
					type: "number",
					placeholder: "收件人手机号码",
					icon: "phone_orange",
				},
				physicalPictures: {
					name: "images",
					el: "image",
					value: [],
					maxlength: 3,
					placeholder: "上传实物图",
					icon: "physicalPictures",
				},
				specifications: {
					weight: {
						name: "weight",
						el: "input",
						value: "",
						maxlength: 9,
						type: "text",
						placeholder: "填写重量",
						icon: "weight",
					},
					size: {
						name: "size",
						el: "input",
						value: "",
						maxlength: 16,
						type: "text",
						placeholder: "填写尺寸",
						icon: "size",
					},
				},
				whetherNeedCarry: {
					name: "is_carry",
					el: "switch",
					type: "checkbox",
					checked: false,
					data: "0",
					placeholder: "是否需要搬运",
					icon: "choose_orange",
				},
				price: {
					name: "total_fee",
					el: "input",
					type: "digit",
					value: "",
					placeholder: "填写价格",
					icon: "price",
				},
			},
			carry: {
				goodsType: {
					name: "cid",
					el: "picker",
					mode: "selector",
					range: [],
					rangeKey: "name",
					value: "",
					placeholder: "选择货品类型",
					next: true,
					icon: "choose_orange",
				},
				physicalPictures: {
					name: "carry_images",
					el: "image",
					value: [],
					maxlength: 3,
					placeholder: "上传实物图",
					icon: "physicalPictures",
				},
				specifications: {
					weight: {
						name: "carry_weight",
						el: "input",
						value: "",
						maxlength: 9,
						type: "text",
						placeholder: "填写重量",
						icon: "weight",
					},
					size: {
						name: "carry_size",
						el: "input",
						value: "",
						maxlength: 16,
						type: "text",
						placeholder: "填写尺寸",
						icon: "size",
					},
				},
				loadNumber: {
					name: "un_num",
					el: "input",
					value: "",
					maxlength: 3,
					type: "number",
					placeholder: "输入装卸人数",
					icon: "user_orange",
				},
				loadAddress: {
					name: "un_address",
					el: "label",
					type: "text",
					value: "",
					placeholder: "选择装卸地址",
					next: true,
					icon: "address",
				},
				installDate: {
					name: "un_time",
					el: "dateTimePicker",
					value: "",
					start: formatDate(),
					placeholder: "选择装卸时间",
					next: true,
					icon: "time",
				},
				whetherNeedInstall: {
					name: "is_install",
					el: "switch",
					type: "checkbox",
					checked: false,
					data: "0",
					placeholder: "是否需要安装",
					icon: "choose_blue",
				},
				price: {
					name: "carry_fee",
					el: "input",
					type: "digit",
					value: "",
					placeholder: "填写价格",
					icon: "price",
				},
			},
			install: {
				goodsType: {
					name: "cid",
					el: "picker",
					mode: "selector",
					range: [],
					rangeKey: "name",
					value: "",
					placeholder: "选择货品类型",
					next: true,
					icon: "choose_orange",
				},
				physicalPictures: {
					name: "install_images",
					el: "image",
					value: [],
					maxlength: 3,
					placeholder: "上传实物图",
					icon: "physicalPictures",
				},
				specifications: {
					weight: {
						name: "install_weight",
						el: "input",
						value: "",
						maxlength: 9,
						type: "text",
						placeholder: "填写重量",
						icon: "weight",
					},
					size: {
						name: "install_size",
						el: "input",
						value: "",
						maxlength: 16,
						type: "text",
						placeholder: "填写尺寸",
						icon: "size",
					},
				},
				installNumber: {
					name: "install_num",
					el: "input",
					value: "",
					maxlength: 3,
					type: "number",
					placeholder: "输入安装人数",
					icon: "user_green",
				},
				installDate: {
					name: "install_time",
					el: "dateTimePicker",
					value: "",
					start: formatDate(),
					placeholder: "选择安装时间",
					next: true,
					icon: "time",
				},
				installAddress: {
					name: "install_address",
					el: "label",
					type: "text",
					value: "",
					placeholder: "选择安装地址",
					next: true,
					icon: "address",
				},
				price: {
					name: "install_fee",
					el: "input",
					type: "digit",
					value: "",
					placeholder: "填写价格",
					icon: "price",
				},
			},
		};

		onLoad({ tabName }: AnyObject) {
			this.$request.get("/type/list").then(({ data }) => {
				Object.values(this.viewModel).forEach((section) => (section.goodsType.range = data));
			});
			tabName && this.switchTab(tabName);
		}

		switchTab(key: string) {
			const { whetherNeedCarry, whetherNeedInstall } = this.viewModel[this.tabKey];
			if (this.tabKey === "transport" && whetherNeedCarry.checked) return;
			if (this.tabKey === "carry" && whetherNeedInstall.checked) return;
			this.tabKey = key;
		}

		operation(e: any, optionKey: string, itemKey: string) {
			const option = this.viewModel[this.tabKey][optionKey];
			switch (optionKey) {
				case "sendAddress":
				case "receiveAddress":
				case "installAddress":
				case "loadAddress":
					uni.chooseLocation({
						success(res) {
							option.value = res.name;
							option.data = JSON.stringify(res);
						},
					});
					break;
				case "distributionDate":
				case "installDate":
					option.value = e;
					option.data = Date.parse(e.replace(/-/g, "/")) / 1000;
					break;
				case "sender":
				case "senderPhoneNumber":
				case "receiver":
				case "receiverPhoneNumber":
				case "price":
				case "installNumber":
				case "loadNumber":
					option.value = option.data = e.detail.value;
					break;
				case "physicalPictures":
					uni.chooseImage({
						count: option.maxlength - option.value.length,
						success: ({ tempFilePaths }) => {
							uni.showToast({ title: "Uploading...", icon: "loading" });
							(tempFilePaths as string[]).forEach(async (filePath) => {
								const [uploadFail, uploadRes]: any = await uni.uploadFile({
									url: $config.API_URL + "/upload",
									filePath,
									name: "file",
									header: {
										Authorization: Storage.get("authorization").access_token,
									},
								});

								if (uploadFail) {
									uni.showToast({
										title: uploadFail.errMsg,
										icon: "none",
									});
									return;
								}

								const { errcode, errmsg: title, data } = JSON.parse(uploadRes.data);

								if (errcode) {
									uni.showToast({
										title,
										icon: "none",
									});
									return;
								}

								option.value.push(filePath);
								option.data ? option.data.push(data.img) : (option.data = [data.img]);
							});
						},
					});
					break;
				case "specifications":
					option[itemKey].value = option[itemKey].data = e.detail.value;
					break;
				case "whetherNeedCarry":
				case "whetherNeedInstall":
					option.data = Number(e.detail.value).toString();
					option.checked = e.detail.value;
					break;
				case "goodsType":
					option.value = option.range[+e.detail.value].name;
					option.data = option.range[+e.detail.value].id.toString();
					break;
				default:
					console.log(optionKey);
					break;
			}
		}

		async tapPhotos(optionKey: string, current: any) {
			const [showFail, result]: any = await uni.showActionSheet({
				itemList: ["预览", "删除"],
			});

			if (showFail) return;

			const option = this.viewModel[this.tabKey][optionKey];
			!result.tapIndex
				? uni.previewImage({ urls: option.value, current })
				: ["value", "data"].forEach((key) => option[key].splice(current, 1));
		}

		public nextStep(): void {
			const { viewModel, tabKey, submitParams } = this,
				{
					transport: { whetherNeedCarry },
					carry: { whetherNeedInstall },
				} = viewModel,
				options = viewModel[tabKey];

			submitParams[tabKey] = [];

			const verifyParams = Object.values(options).every((option: any) => {
				if (!option.el) {
					return Object.values(option).every((item: any) => {
						submitParams[tabKey].push([
							item.name,
							Array.isArray(item.data) ? item.data.toString() : item.data,
						]);

						return Boolean(
							item?.data?.toString() ||
								uni.showToast({
									title: item.placeholder,
									icon: "none",
									success: () => false,
								})
						);
					});
				}

				submitParams[tabKey].push([
					option.name,
					Array.isArray(option.data) ? option.data.toString() : option.data,
				]);

				return Boolean(
					option?.data?.toString() ||
						uni.showToast({
							title: option.placeholder,
							icon: "none",
							success: () => false,
						})
				);
			});

			if (!verifyParams) return;

			if (tabKey === "transport" && whetherNeedCarry.checked) {
				this.tabKey = "carry";
				return;
			}
			if (tabKey === "carry" && whetherNeedInstall.checked) {
				this.tabKey = "install";
				return;
			}

			const submitData = (...arg: string[]) => {
				const params: [string, any][] = [];
				for (const paramsKey in submitParams) {
					arg.forEach((key) => {
						if (paramsKey === key) {
							params.push(...submitParams[paramsKey]);
						}
					});
				}

				this.$request
					.post("/order/create", {
						type: ["transport", "install", "carry"].indexOf(this.tabKey) + 1,
						...Object.fromEntries(params),
					})
					.then(({ data }) =>
						uni.navigateTo({
							url: `/pages/home/ConfirmOrder?order_id=${data.id}`,
						})
					);
			};

			switch (true) {
				case whetherNeedCarry?.checked && whetherNeedInstall?.checked:
					submitData("transport", "carry", "install");
					break;
				case whetherNeedCarry?.checked:
					submitData("transport", "carry");
					break;
				case whetherNeedInstall?.checked:
					submitData("carry", "install");
					break;
				default:
					submitData(tabKey);
					break;
			}
		}
	}
</script>

<style>
	page,
	.root {
		height: 100%;
	}
</style>
<style lang="scss" scoped>
	::v-deep {
		switch {
			transform: scale(0.6);
			.wx-checkbox-input,
			.uni-checkbox-input {
				border-radius: 50%;
				border-color: #3ec483;
				background-color: transparent;
			}

			.wx-checkbox-input.wx-checkbox-input-checked,
			.uni-checkbox-input.uni-checkbox-input-checked {
				background-color: #3ec483;
			}

			&:not([disabled]) {
				.wx-checkbox-input:hover,
				.uni-checkbox-input:hover {
					border-color: #3ec483;
				}
			}
		}
	}
	.top-bar {
		padding: 20rpx;
		margin: 10rpx 30rpx;
		&.active {
			position: relative;
			color: #3ec483;
			&::after {
				content: "";
				position: absolute;
				bottom: 0;
				height: 5rpx;
				width: 60%;
				background-color: #3ec483;
			}
		}
	}
</style>